package com.aliyun.heiyu.powermaster.server.rotary.task;

import com.aliyun.heiyu.powermaster.server.rotary.dao.AlgorithmDAO;
import com.aliyun.heiyu.powermaster.server.rotary.dao.impl.AlgorithmDAOImpl;
import com.aliyun.heiyu.powermaster.server.rotary.object.entity.AlgorithmEntity;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description 定时器管理
 * @Author shun.zhang
 * @Date 2020/9/14 15:57
 **/
public class Task {
    private static Logger logger = LoggerFactory.getLogger(Task.class);
    static Scheduler scheduler;
    static Scheduler jobScheduler;
    public static AlgorithmEntity algo;
    private AlgorithmDAO algorithmDAO;
    //模型训练推荐曲线任务
    public static JobDetail modelJob = null;

    public Task() {
        algorithmDAO = new AlgorithmDAOImpl();
        try {
            scheduler = StdSchedulerFactory.getDefaultScheduler();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取pdu动态数据
        getPduDataTask();
        //获取空调动态数据
        getAirDataTask();
        //定时检测退出用户
        uerOutTask();
        //制冷策略调节空调温度
        algoForeTask();

        stateGridPowerctlAgentServerPerformanceTask();
    }
    public Task(int i){
        algorithmDAO = new AlgorithmDAOImpl();
    }
    /**
     * 重启model模型
     */
    public  void reStartModel() {
        if (null != modelJob) {
            try {
                logger.info("关闭制冷策略定时器");
                jobScheduler.shutdown();
                logger.info("启动制冷策略定时器");
                algoForeTask();
            }catch (Exception e){
                logger.error(e.getMessage());
            }
        }
    }

    /**
     * 用户定时退出定时器
     */
    public void uerOutTask() {
        try {
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("user_Data", "user")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(10)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();

            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            JobDetail job = JobBuilder.newJob(UserOutTask.class)
                .withIdentity("user", "user")
                .usingJobData("user_job", "user_data")
                .withDescription("用户定时退出定时器")
                .build();
            //4.调度器 中加入 任务和触发器
            scheduler.scheduleJob(job, trigger);
            //5.启动任务调度
            scheduler.start();
        } catch (Exception e) {
            logger.error("用户定时退出定时器异常", e);
        }
    }

    /**
     * arm 数据采集
     */
    public void stateGridPowerctlAgentServerPerformanceTask() {
        try {
            logger.info("进入定时stateGridPowerctlAgentServerPerformanceTask开始");
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("StateGridPowerctlAgentServerPerformance_Data", "StateGridPowerctlAgentServerPerformance")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(30)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();

            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            JobDetail job = JobBuilder.newJob(StateGridPowerctlAgentServerPerformanceTask.class)
                .withIdentity("StateGridPowerctlAgentServerPerformance", "StateGridPowerctlAgentServerPerformance")
                .usingJobData("StateGridPowerctlAgentServerPerformance_job", "StateGridPowerctlAgentServerPerformance_data")
                .withDescription("arm数据采集定时退出定时器")
                .build();
            //4.调度器 中加入 任务和触发器
            scheduler.scheduleJob(job, trigger);
            //5.启动任务调度
            scheduler.start();
        } catch (Exception e) {
            logger.error("arm数据采集定时器异常", e);
        }
    }

    /**
     * 获取空调数据任务方法
     */
    public void getPduDataTask() {
        try {
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("pdu_Data", "pdu")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(30)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();

            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            JobDetail job = JobBuilder.newJob(PduDataTask.class)
                .withIdentity("pdu", "pdu")
                .usingJobData("pdu_job", "pdu_data")
                .withDescription("获取pdu数据")
                .build();
            //4.调度器 中加入 任务和触发器
            scheduler.scheduleJob(job, trigger);
            //5.启动任务调度
            scheduler.start();
        } catch (Exception e) {
            logger.error("获取pdu数据的定时器异常", e);
        }
    }

    /**
     * 空调推荐温度定时器
     */
    public void airRecommendTask() {
        try {
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("air_recom_tri", "air")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(300)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();
            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            JobDetail job = JobBuilder.newJob(AirRecommendTask.class)
                .withIdentity("air_recom_id", "air_Recom")
                .usingJobData("air_recom_jod", "air_Recom")
                .withDescription("空调推荐温度")
                .build();
            //4.调度器 中加入 任务和触发器
            scheduler.scheduleJob(job, trigger);
            //5.启动任务调度
            scheduler.start();
        } catch (Exception e) {
            logger.error("空调推荐温度的定时器异常", e);
        }
    }

    /**
     * 获取空调数据任务方法
     */
    public void getAirDataTask() {
        try {
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("air_Data", "air")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(30)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();

            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            JobDetail job = JobBuilder.newJob(GetAirDataTask.class)
                .withIdentity("air_airDny", "airData")
                .usingJobData("air_job", "air_data")
                .withDescription("获取空调数据")
                .build();
            //4.调度器 中加入 任务和触发器
            scheduler.scheduleJob(job, trigger);
            //5.启动任务调度
            scheduler.start();
        } catch (Exception e) {
            logger.error("获取空调数据的定时器异常", e);
        }
    }

    /**
     * 模型训练推荐温度
     */
    public void algoForeTask() {
        logger.info("执行制冷策略训练推荐温度定时器algoForeTask");
        try {
            int time = getTime();
            logger.info("定时:[{}s] 执行一次制冷策略训练推荐温度",time);
            if(time < 0){
                time = 60;
            }
            //1.创建scheduler，调度器
            //2.定义一个Trigger,触发条件类
            jobScheduler = StdSchedulerFactory.getDefaultScheduler();
            TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
            triggerBuilder.withIdentity("algo_Data", "model")
                //一旦加入scheduler，立即生效，即开始时间
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    //规定时间执行一次（s）
                    .withIntervalInSeconds(time)
                    //一直执行，直到结束时间
                    .repeatForever());
            Trigger trigger = triggerBuilder.build();

            //3.定义一个JobDetail
            //定义Job类为HelloQuartz类，这是真正的执行逻辑所在
            modelJob = JobBuilder.newJob(AlgoForecastTask.class)
                .withIdentity("model_airDny", "model_iden")
                .usingJobData("model_job", "model_job")
                .withDescription("制冷策略推荐温度")
                .build();
            //4.调度器 中加入 任务和触发器
            jobScheduler.scheduleJob(modelJob, trigger);
            //5.启动任务调度
            jobScheduler.start();
        } catch (Exception e) {
            logger.error("制冷策略推荐温度异常", e);
        }
    }

    /**
     * 获取模型训练推荐温度定时时间
     * @return
     */
    private int getTime(){
        logger.info("更新推荐温度定时时间");
        if(null == algo){
            logger.info("空调策略为空，重新获取策略");
            AlgorithmEntity algoUse = algorithmDAO.queryAlgoUse();
            if(null == algoUse){
                AlgorithmEntity al = new AlgorithmEntity();
                al.setCooling_allowance(1);
                al.setControl_frequency(1);
                al.setTemp_precision(1);
                algo = al;
            }else {
                algo = algoUse;
            }

        }
        int value = 1;
        try {
             value = Double.valueOf(algo.getControl_frequency()).intValue();
        }catch (Exception e){
            value = 1;
        }
        int result = 60 / value;
        logger.info("更新时间为:{}",result);
        return result;
    }

}
